import requests
import time
import json
import random
import threading
import cv2
import numpy as np
from datetime import datetime
import sys
import threading
import atexit
from plate_rec import get_plate, process_video

# 全局变量，用于控制视频处理线程
video_thread = None
stop_event = threading.Event()

def run_video_processing():
    """视频处理线程函数"""
    video_path = "E:\\learning\\杂\\ae63a-main\\ae63a-main\\车牌识别视频\\Video007.mp4"
    while not stop_event.is_set():
        try:
            process_video(video_path, frame_skip=2)  # 使用摄像头，每处理1帧跳过2帧
            # test()
        except Exception as e:
            print(f"视频处理出错: {e}")
            time.sleep(1)  # 出错时等待1秒后重试

def start_video_processing():
    """启动视频处理线程"""
    global video_thread, stop_event
    stop_event.clear()
    if video_thread is None or not video_thread.is_alive():
        video_thread = threading.Thread(target=run_video_processing, daemon=True)
        video_thread.start()
        print("视频处理线程已启动")

def stop_video_processing():
    """停止视频处理线程"""
    global stop_event
    stop_event.set()
    if video_thread and video_thread.is_alive():
        video_thread.join(timeout=2.0)
        print("视频处理线程已停止")

# 注册程序退出时的清理函数
atexit.register(stop_video_processing)

# 启动视频处理线程
start_video_processing()

class PythonClient:
    def __init__(self, server_url="http://localhost:5000", client_id="python_client_1"):
        """
        初始化客户端
        
        参数:
            server_url (str): 服务器URL
            client_id (str): 客户端ID，如果未提供则随机生成
        """
        self.server_url = server_url
        self.client_id = client_id
        self.plate_id = ""  # 默认车牌号
        self.is_running = False
        self.heartbeat_interval = 10  # 心跳间隔10秒
        self.data_interval = 1        # 数据发送间隔1秒
        
        # 初始化摄像头
        self.cap = cv2.VideoCapture(0)
        if not self.cap.isOpened():
            print("警告: 无法打开摄像头，将使用模拟数据")
            self.cap = None
        
    def send_heartbeat(self):
        """发送心跳包"""
        try:
            heartbeat_data = {
                "clientId": self.client_id,
                "status": "alive",
                "timestamp": datetime.now().isoformat()
            }
            
            response = requests.post(
                f"{self.server_url}/api/heartbeat",
                json=heartbeat_data,
                timeout=5
            )
            
            if response.status_code == 200:
                result = response.json()
                # 安全地获取消息，避免 KeyError
                message = result.get('message', '心跳成功')
                print(f"[{datetime.now().strftime('%H:%M:%S')}] 心跳发送成功: {message}")
            else:
                print(f"[{datetime.now().strftime('%H:%M:%S')}] 心跳发送失败: {response.status_code}")
                
        except requests.exceptions.RequestException as e:
            print(f"[{datetime.now().strftime('%H:%M:%S')}] 心跳发送错误: {e}")
        except Exception as e:
            print(f"[{datetime.now().strftime('%H:%M:%S')}] 处理心跳响应时出错: {e}")
    
    # def detect_plate_from_camera(self):
    #     """
    #     从摄像头捕获一帧并识别车牌
        
    #     返回:
    #         str: 识别到的车牌号，如果未识别到则返回None
    #         numpy.ndarray or None: 带标注的图像，如果不需要可视化则为None
    #     """
    #     if self.cap is None:
    #         return None, None
            
    #     ret, frame = self.cap.read()
    #     if not ret:
    #         print("无法从摄像头获取图像")
    #         return None, None
            
    #     # 调用车牌识别函数，设置visualize=True获取带标注的图像
    #     plate_number, annotated_frame = detect_plate(frame=frame, visualize=True)
        
    #     return plate_number, annotated_frame
    
    def send_data(self):
        """
        发送识别到的车牌数据到服务器
        
        如果摄像头可用，则从摄像头捕获并识别车牌；
        """
        try:
            self.plate_id = get_plate()
            # 准备发送的数据
            sensor_data = {
                "clientId": self.client_id,
                "plateId": self.plate_id,
                "timestamp": datetime.now().isoformat()
            }
            
            response = requests.post(
                f"{self.server_url}/api/data",
                json=sensor_data,
                timeout=5
            )
            
            if response.status_code == 200:
                result = response.json()
                # 安全地获取消息，使用 get 方法避免 KeyError
                status = result.get('status', 'unknown')
                message = result.get('message', '数据接收成功')
                received_at = result.get('received_at', '未知时间')
                
                print(f"[{datetime.now().strftime('%H:%M:%S')}] 数据发送成功 - 状态: {status}")
                print(f"    服务器消息: {message}")
                print(f"    接收时间: {received_at}")
            else:
                print(f"[{datetime.now().strftime('%H:%M:%S')}] 数据发送失败: {response.status_code}")
                try:
                    error_detail = response.json()
                    print(f"    错误详情: {error_detail}")
                except:
                    print(f"    错误内容: {response.text}")
                
        except requests.exceptions.RequestException as e:
            print(f"[{datetime.now().strftime('%H:%M:%S')}] 数据发送错误: {e}")
        except Exception as e:
            print(f"[{datetime.now().strftime('%H:%M:%S')}] 处理数据响应时出错: {e}")
    
    def heartbeat_worker(self):
        """心跳工作线程"""
        while self.is_running:
            self.send_heartbeat()
            time.sleep(self.heartbeat_interval)
    
    def data_worker(self):
        """数据发送工作线程"""
        while self.is_running:
            self.send_data()
            time.sleep(self.data_interval)
    
    def check_server_health(self):
        """检查服务器健康状态"""
        try:
            response = requests.get(f"{self.server_url}/api/health", timeout=5)
            if response.status_code == 200:
                health_data = response.json()
                print(f"服务器状态: {health_data.get('status', 'unknown')}")
                print(f"客户端数量: {health_data.get('client_count', 0)}")
                print(f"服务器时间: {health_data.get('server_time', '未知')}")
                return True
            else:
                print(f"服务器健康检查失败: {response.status_code}")
                return False
        except requests.exceptions.RequestException as e:
            print(f"无法连接到服务器: {e}")
            return False
    
    def start(self):
        """启动客户端"""
        print(f"启动 Python 客户端: {self.client_id}")
        print(f"目标服务器: {self.server_url}")
        
        # 检查服务器连接
        if not self.check_server_health():
            print("无法连接到服务器，请检查服务器是否运行")
            return
        
        self.is_running = True
        
        # 启动心跳线程
        heartbeat_thread = threading.Thread(target=self.heartbeat_worker)
        heartbeat_thread.daemon = True
        heartbeat_thread.start()
        
        # 启动数据发送线程
        data_thread = threading.Thread(target=self.data_worker)
        data_thread.daemon = True
        data_thread.start()
        
        print("客户端已启动，按 Ctrl+C 停止...")
        
        try:
            while self.is_running:
                time.sleep(1)
        except KeyboardInterrupt:
            self.stop()
    
    def stop(self):
        """停止客户端"""
        print("\n正在停止客户端...")
        self.is_running = False

if __name__ == "__main__":
    # 可以从命令行参数获取配置
    server_url = sys.argv[1] if len(sys.argv) > 1 else "http://localhost:5000"
    client_id = sys.argv[2] if len(sys.argv) > 2 else f"python_client_{random.randint(1000, 9999)}"
    
    client = PythonClient(server_url, client_id)
    client.start()